﻿using System.Collections.Generic;
using System.Diagnostics;

namespace ReadyApps.Common
{
    /// <summary>
    /// Provides access to the global settings of the ReadyApps system through
    /// static properties.
    /// </summary>
    public class ReadyAppsSettings
    {
        #region Constants

        /// <summary>
        /// The default page name used throughout the wiki control when no page
        /// name is supplied.
        /// </summary>
        /// <remarks>
        /// This is the page name that is used when no page is supplied on a
        /// wiki page request. Changing this value after deployment would
        /// create unpredictable results which most likely would include many
        /// "orphaned" pages and broken links within the wiki system. Changing
        /// this should cause at least some of the unit tests to fail.
        /// </remarks>
        public const string DEFAULT_PAGE_NAME = "Default";

        #endregion

        #region Variables

        private static IAppSettings appSettings;

        #endregion

        #region Properties

        /// <summary>
        /// Gets the connection string name for the configured data provider.
        /// </summary>
        public static string WikiConnectionStringName
        {
            get { return appSettings.WikiConnectionStringName; }
        }

        /// <summary>
        /// Gets the wiki data provider type name for runtime instantiation.
        /// </summary>
        /// <remarks>
        /// <b>Note to Implementers:</b> Custom types must implement the
        /// <see cref="ReadyApps.Data.IWikiDataProvider"/> interface or a
        /// type-casting exception will be generated at runtime.
        /// </remarks>
        public static string WikiDataProviderTypeName
        {
            get { return appSettings.WikiDataProviderTypeName; }
        }

        /// <summary>
        /// Gets the wiki data provider's source assembly for runtime instantiation.
        /// </summary>
        /// <remarks>
        /// If not supplied, it is assumed that the type is within the ReadyApps assembly.
        /// If supplied, custom data providers may be instantiated from non-local types as
        /// long as they implement the <see cref="ReadyApps.Data.IWikiDataProvider"/> interface. Currently
        /// the list of types that may omit this property are as follows:
        /// <list type="bullet">
        /// <item>Oracle Database data source - <see cref="ReadyApps.Data.Oracle.OracleWikiDataProvider"/></item>
        /// </list>
        /// </remarks>
        /// <seealso cref="ReadyApps.Data.Oracle.OracleWikiDataProvider"/>
        public static string WikiDataProviderAssembly
        {
            get { return appSettings.WikiDataProviderAssembly; }
        }

        /// <summary>
        /// Gets the base path of for the CKEditor html files on the server.
        /// </summary>
        public static string CKEditorBasePath
        {
            get { return appSettings.CKEditorBasePath; }
        }

        /// <summary>
        /// Gets the components that have been configured for tracing in the
        /// configuration file.
        /// </summary>
        public static TraceComponent EnabledComponents
        {
            get { return appSettings.EnabledComponents; }
        }

        /// <summary>
        /// Gets the level of tracing that the system is configured for.
        /// </summary>
        public static TraceLevel EnabledLevel
        {
            get { return appSettings.EnabledLevel; }
        }

        /// <summary>
        /// Gets the mappings for URL routes to pages that contain a wiki control.
        /// </summary>
        /// <remarks>
        /// In order for routing to work, the ASP.Net routing system must be configured at
        /// application start-up. These mappings are configured in the web application's
        /// configuration file and loaded by calling a static method in the ReadyApps
        /// assembly.
        /// <code lang="xml" title="Example WikiMappings Configuration Section">
        /// <wikiMappings>
        ///   <add name="MainWiki" urlPrefix="Wiki" mapTo="~/WikiBase.aspx"/>
        /// </wikiMappings>
        /// </code>
        /// The above example creates a route named <i>MainWiki</i> that matches anything that has
        /// a folder of <i>Wiki</i> and redirects it to the <i>WikiBase.aspx</i> page, so
        /// <i>mySiteRootFolder/Wiki</i> goes to <i>WikiBase.aspx</i>, but <i>mySiteRootFolder/WikiLinks</i>
        /// does not get routed and is handled normally. It is assumed that this page has a wiki
        /// control contained within it.
        /// </remarks>
        public static IEnumerable<WikiMapping> WikiMappings
        {
            get { return appSettings.WikiMappings; }
        }

        #endregion

        #region Constructor

        /// <summary>
        /// Initializes the static components of the <see cref="ReadyAppsSettings"/> object
        /// to their default runtime values.
        /// </summary>
        /// <remarks>
        /// The settings values are retrieved from the <see cref="ReadyAppsConfigurationSection"/>
        /// object by default at runtime.
        /// </remarks>
        static ReadyAppsSettings()
        {
            appSettings = new AppConfigurationSettings();
        }

        #endregion

        #region Testing Helpers

        /// <summary>
        /// Sets the static settings object for use in unit testing the ReadyApps controls.
        /// </summary>
        /// <param name="substituteSettings">An object that implements the <see cref="IAppSettings"/>
        /// interface to be used in place of the default settings object</param>
        internal static void SetAppSettings(IAppSettings substituteSettings)
        {
            appSettings = substituteSettings;
        }

        #endregion
    }
}
